package com.wzc.basic.service.impl;

import com.wzc.basic.constant.RegisterConstant;
import com.wzc.basic.exception.BusinessException;
import com.wzc.basic.service.IVerifyCodeService;
import com.wzc.basic.util.StrUtils;
import com.wzc.basic.util.VerifyCodeUtils;
import com.wzc.user.domain.User;
import com.wzc.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;


    /**
     * 图形验证码
     * @param key
     * @return
     */
    @Override
    public String getVerifyCode(String key) {
        // 校验图形验证码是否为空
        if(StringUtils.isEmpty(key)){
            throw new BusinessException("网络异常");
        }
        // 生成随机验证码
        String code = StrUtils.getComplexRandomString(4);

        // 将生成的验证码code存入redis，并设置有限时限
        redisTemplate.opsForValue().set(key,code,3, TimeUnit.MINUTES);

        // 生成一个base64位的字符串
        return VerifyCodeUtils.verifyCode(80,40,code);
    }

    /**
     * 手机验证码
     * @param map
     */
    @Override
    public void smsCode(Map<String, String> map) {
        String phone = map.get("phone"); // 手机号码
        String imageCode = map.get("imageCode"); // 图形验证码
        String imageCodeKey = map.get("imageCodeKey"); // 图形验证码对应的key

        // 判断页面传参（phone   imageCode    imageCodeKey）是否为空
        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(imageCode) || StringUtils.isEmpty(imageCodeKey)){
            throw new BusinessException("参数为空，请重新输入！");
        }

        // 图形验证码校验
        Object obj = redisTemplate.opsForValue().get(imageCodeKey); // 从redis中获取图形验证码
        if(obj==null){
            throw new BusinessException("图形验证码以过期，请重新获取输入!");
        }
        // equalsIgnoreCase(imageCode) 图形验证码不区分大小写
        if(!obj.toString().equalsIgnoreCase(imageCode)){
            throw new BusinessException("图形验证码输入错误，请重新输入!");
        }

        // 通过手机号码查询user表判断是否被注册过
        User user = userMapper.findByPhone(phone);
        if(user != null){
            throw new BusinessException("当前号码已注册，请使用密码登录!");
        }

        // 判断是否是第一次发送请求或者验证码是否过期
        Object value = redisTemplate.opsForValue().get(phone + "phoneRegister"); // 从redis中获取手机号码
        String code = null;
        if(value == null){ // redis 中没有值（手机号码，第一次获取验证码）
            code = StrUtils.getComplexRandomString(6); // 调用StrUtils生成随机验证码
        } else { // redis中有值（验证码已经发过，判断时间是否超过一分钟）
            String redisTime = value.toString().split(":")[1];
            Long ltime = Long.valueOf(redisTime);
            // 验证码没超过一分钟，提示用户一分钟之内不能多次发送
            if(System.currentTimeMillis() - ltime< 1*60*1000){
                throw new BusinessException("一分钟之内不能发送多次！");
            } else { // 验证码超过了一分钟，刷新过期时间
                code = value.toString().split(":")[0];
            }
        }
        // 重新将code存到redis
        redisTemplate.opsForValue().set(
                phone + "phoneRegister",
                code + ":" + System.currentTimeMillis(),
                3,
                TimeUnit.MINUTES);
        // 调用SmsSendUtil   将验证码发送给用户
        // SmsSendUtil.smsSend(phone,"您的验证码为："+ code +",请在三分钟之内使用");
        System.out.println("您的验证码为："+ code +",请在三分钟之内使用");
    }


    @Override
    public void binderSmsCode(Map<String, String> map) {
        String phone = map.get("phone"); // 手机号码

        // 判断页面传参（phone）是否为空
        if(StringUtils.isEmpty(phone)){
            throw new BusinessException("手机号为空，请重新输入！");
        }

        // 判断是否是第一次发送请求或者验证码是否过期
        Object value = redisTemplate.opsForValue().get(phone + RegisterConstant.WXBINDER); // 从redis中获取手机号码
        String code = null;
        if(value == null){ // redis 中没有值（手机号码，第一次获取验证码）
            code = StrUtils.getComplexRandomString(6); // 调用StrUtils生成随机验证码
        } else { // redis中有值（验证码已经发过，判断时间是否超过一分钟）
            String redisTime = value.toString().split(":")[1];
            Long ltime = Long.valueOf(redisTime);
            // 验证码没超过一分钟，提示用户一分钟之内不能多次发送
            if(System.currentTimeMillis() - ltime< 1*60*1000){
                throw new BusinessException("一分钟之内不能发送多次！");
            } else { // 验证码超过了一分钟，刷新过期时间
                code = value.toString().split(":")[0];
            }
        }
        // 重新将code存到redis
        redisTemplate.opsForValue().set(
                phone + RegisterConstant.WXBINDER,
                code + ":" + System.currentTimeMillis(),
                3,
                TimeUnit.MINUTES);
        // 调用SmsSendUtil   将验证码发送给用户
        // SmsSendUtil.smsSend(phone,"您的验证码为："+ code +",请在三分钟之内使用");
        System.out.println("您的验证码为："+ code +",请在三分钟之内使用");

    }
}
